package com.his.core.utils;

import java.util.*;

public class IPWhiteList {

    private static Set<String> getIpRange(String ip){
        int start;
        int end;

        Set<String> list = new HashSet<>();
        if(ip.contains("/")){
            Collections.addAll(list, ip.split("/"));
            return list;
        }else if (ip.contains("*")){
            start = 0;
            end = 255;
        }else if (ip.contains("-")){
            start = Integer.parseInt(ip.split("-")[0]);
            end = Integer.parseInt(ip.split("-")[1]);
        }else {
            start = Integer.parseInt(ip);
            end = Integer.parseInt(ip);
        }

        for (int i = start; i <= end; i++){
            list.add(i+"");
        }
        return list;
    }

    private static List<String> ipList(String allows){
        List<String> list = new ArrayList<>();
        for (String allow : allows.split(";")){
            for (String ipstr : getIpRange(allow.split("\\.")[0])){
                for (String ipstr1 : getIpRange(allow.split("\\.")[1])){
                    String ip1 = ipstr + "." + ipstr1;
                    for (String ipstr2 : getIpRange(allow.split("\\.")[2])){
                        String ip2 = ip1 + "." + ipstr2;
                        for (String ipstr3 : getIpRange(allow.split("\\.")[3])){
                            String ip3 = ip2 + "." + ipstr3;
                            list.add(ip3);
                        }
                    }
                }
            }
        }
        Collections.sort(list);

        return list;
    }

    public static boolean validate(String targetIP, String allows){
        for (String allow : allows.split(";")){
            if (validIp(targetIP, allow)){
                return true;
            }
        }
        return false;
    }

    private static boolean validIp(String targetIP, String allow){
        String[] tars = targetIP.split("\\.");
        String[] alls = allow.split("\\.");
        for (int i = 0; i < 4; i++){
            if (!valid(tars[i], alls[i])){
                return false;
            }
        }
        return true;
    }

    private static boolean valid(String tar, String all){
        if ("*".equals(all)){
            return true;
        }
        if (tar.equals(all)){
            return true;
        }
        if (all.contains("/")){
            String[] alls = all.split("/");
            if (tar.equals(alls[0])
                    || tar.equals(alls[1])){
                return true;
            }
        }
        if (all.contains("-")){
            String[] alls = all.split("-");
            return Integer.parseInt(tar) >= Integer.parseInt(alls[0])
                    && Integer.parseInt(tar) <= Integer.parseInt(alls[1]);
        }
        return false;
    }



    public static void main(String[] args) {

        String ipWhilte = "192.168.1.1;" +                 //设置单个IP的白名单
                "192.168.2.*;" +                 //设置ip通配符,对一个ip段进行匹配
                "192.168.3.17-38;" +
                "192.168.*.0";     //设置一个IP范围
        long t = System.currentTimeMillis();
        System.out.println(ipList(ipWhilte).contains("192.168.3.16"));
        System.out.println(ipList(ipWhilte).contains("192.168.3.17"));
        System.out.println(ipList(ipWhilte).contains("192.168.3.18"));
        System.out.println(ipList(ipWhilte).contains("192.168.5.0"));
        System.out.println(System.currentTimeMillis() - t);

        long t1 = System.currentTimeMillis();
        System.out.println(validate("192.168.3.16", ipWhilte));
        System.out.println(validate("192.168.3.17", ipWhilte));
        System.out.println(validate("192.168.3.18", ipWhilte));
        System.out.println(validate("192.168.5.0", ipWhilte));
        System.out.println(System.currentTimeMillis() - t1);



    }


}
